package com.mongo.service;

import com.mongo.func.SFunction;
import com.mongo.service.impl.LambdaQuery;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import java.util.Collection;
import java.util.List;


/**
 * 提供mongo的lambda查询操作
 * @author xiazhun
 * @create 2022/5/26
 */
public interface LambdaMongoQuery<T>{

     /**
      * 查询
      * @return T 如果query为没有绑定Criteria,返回第一个数据(T)
      */
     T query();

     /**
      * 查询
      * @param fields 查询指定字段
      * @return this
      */
     LambdaQuery<T> include(String ...fields);

     /**
      * 查询
      * @param fields 排除指定字段
      * @return this
      */
     LambdaQuery<T> exclude(String ...fields);

     /**
      * 获取当前查询
      * @return {@link Query}
      */
     Query getQuery();

     /**
      * 查询集合
      * @return T集合
      */
     List<T> list();

     T one();

     /**
      * 等于查询
      * @param function 字段
      * @param value 值
      * @return lambda
      */
     LambdaQuery<T> eq(SFunction<T,?> function, Object value);

     /**
      * 等于查询
      * @param condition 执行条件
      * @param function 字段
      * @param value 值
      * @return lambda
      */
     LambdaQuery<T> eq(boolean condition, SFunction<T,?> function, Object value);

     /**
      * 包含查询
      * @param function 字段
      * @param value 值
      * @return lambda
      */
     LambdaQuery<T> in(SFunction<T,?> function, Object ...value);

     /**
      * 包含查询
      * @param condition 执行条件
      * @param function 字段
      * @param value 值
      * @return lambda
      */
     LambdaQuery<T> in(boolean condition, SFunction<T,?> function, Object ...value);

     /**
      * 包含查询
      * @param function 字段
      * @param value 值
      * @return lambda
      */
     LambdaQuery<T> in(SFunction<T,?> function, Collection<?> value);


     /**
      * 包含查询
      * @param condition 执行条件
      * @param function 字段
      * @param value 值
      * @return lambda
      */
     LambdaQuery<T> in(boolean condition, SFunction<T,?> function, Collection<?> value);

     /**
      * 小于查询
      * @param function 字段
      * @param value 值
      * @return lambda
      */
     LambdaQuery<T> lt(SFunction<T,?> function, Object value);

     /**
      * 小于查询
      * @param condition 执行条件
      * @param function 字段
      * @param value 值
      * @return lambda
      */
     LambdaQuery<T> lt(boolean condition, SFunction<T,?> function, Object value);

     /**
      * 大于查询
      * @param function 字段
      * @param value 值
      * @return lambda
      */
     LambdaQuery<T> gt(SFunction<T,?> function, Object value);

     /**
      * 大于查询
      * @param condition 执行条件
      * @param function 字段
      * @param value 值
      * @return lambda
      */
     LambdaQuery<T> gt(boolean condition, SFunction<T,?> function, Object value);

     /**
      * 小于等于查询
      * @param function 字段
      * @param value 值
      * @return lambda
      */
     LambdaQuery<T> lte(SFunction<T,?> function, Object value);

     /**
      * 小于等于查询
      * @param condition 执行条件
      * @param function 字段
      * @param value 值
      * @return lambda
      */
     LambdaQuery<T> lte(boolean condition, SFunction<T,?> function, Object value);

     /**
      * 大于等于查询
      * @param function 字段
      * @param value 值
      * @return lambda
      */
     LambdaQuery<T> gte(SFunction<T,?> function, Object value);

     /**
      * 大于等于查询
      * @param condition 执行条件
      * @param function 字段
      * @param value 值
      * @return lambda
      */
     LambdaQuery<T> gte(boolean condition, SFunction<T,?> function, Object value);

     /**
      * 不等于查询
      * @param function 字段
      * @param value 值
      * @return lambda
      */
     LambdaQuery<T> not(SFunction<T,?> function, Object value);

     /**
      * 不等于查询
      * @param condition 执行条件
      * @param function 字段
      * @param value 值
      * @return lambda
      */
     LambdaQuery<T> not(boolean condition, SFunction<T,?> function, Object value);

     /**
      * 满足所有查询
      * @param function 字段
      * @param value 值
      * @return lambda
      */
     LambdaQuery<T> allEq(SFunction<T,?> function, Collection<?> value);

     /**
      * 满足所有查询
      * @param condition 执行条件
      * @param function 字段
      * @param value 值
      * @return lambda
      */
     LambdaQuery<T> allEq(boolean condition, SFunction<T,?> function, Collection<?> value);

     /**
      * 精确查询
      * @param function 字段
      * @param criteria 当前条件
      * @return lambda
      */
     LambdaQuery<T> elemMatch(SFunction<T,?> function, Criteria criteria);

     /**
      * 精确查询
      * @param condition 执行条件
      * @param function 字段
      * @param criteria 当前条件
      * @return lambda
      */
     LambdaQuery<T> elemMatch(boolean condition, SFunction<T,?> function, Criteria criteria);

     /**
      * 模糊查询
      * @param condition 执行条件
      * @param function 字段
      * @param value 值
      * @return lambda
      */
     LambdaQuery<T> like(boolean condition, SFunction<T,?> function, Object value, String regex);

     /**
      * 模糊查询
      * @param function 字段
      * @param value 值
      * @return lambda
      */
     LambdaQuery<T> like(SFunction<T,?> function, Object value);

     /**
      * 倒序
      * @param function 字段
      * @return lambda
      */
     LambdaQuery<T> desc(SFunction<T,?> function);

     /**
      * 倒序
      * @param condition 执行条件
      * @param function 字段
      * @return lambda
      */
     LambdaQuery<T> desc(boolean condition, SFunction<T,?> function);

     /**
      * 正序
      * @param function 字段
      * @return lambda
      */
     LambdaQuery<T> asc(SFunction<T,?> function);

     /**
      * 正序
      * @param condition 执行条件
      * @param function 字段
      * @return lambda
      */
     LambdaQuery<T> asc(boolean condition, SFunction<T,?> function);


     /**
      * 在之间
      * @param function 字段
      * @param var1 var1
      * @param var2 var2
      * @return lambda
      */
     LambdaQuery<T> between(SFunction<T,?> function, Object var1, Object var2);

     /**
      * 在之间
      * @param condition 执行条件
      * @param function 字段
      * @param var1 var1
      * @param var2 var2
      * @return lambda
      */
     LambdaQuery<T> between(boolean condition, SFunction<T,?> function, Object var1, Object var2);

     /**
      * 分页
      * @param pageRequest page
      * @return {@link PageImpl}
      */
     PageImpl<T> page(PageRequest pageRequest);
}
